package com.gitee.faster.redis.protocol;

import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.smartboot.socket.Protocol;
import org.smartboot.socket.transport.AioSession;
import redis.clients.jedis.util.RedisInputStream;
import redis.clients.jedis.util.SafeEncoder;

import java.io.ByteArrayInputStream;
import java.nio.ByteBuffer;
import java.util.Collections;
import java.util.List;

import static redis.clients.jedis.Protocol.read;

/**
 * RESP 协议实现
 *
 * @author hongda.li
 */
@Slf4j
public class RedisProtocol implements Protocol<RedisRequest> {

    @SneakyThrows
    @Override
    public RedisRequest decode(ByteBuffer buffer, AioSession session) {
        return new RedisRequest(session.getSessionID(),
                session.getRemoteAddress(),
                this.readFromBuffer(buffer));
    }

    private List<String> readFromBuffer(ByteBuffer buffer) {
        byte[] fromBuffer = new byte[buffer.remaining()];
        buffer.get(fromBuffer);

        Object result = read(new RedisInputStream(new ByteArrayInputStream(fromBuffer)));

        List<String> parsed;

        switch (result) {
            // 单命令
            case byte[] bytes -> parsed = Collections.singletonList(SafeEncoder.encode(bytes));
            // 多命令
            case List<?> list -> parsed = list.stream()
                    .filter(byte[].class::isInstance)
                    .map(byte[].class::cast)
                    .map(SafeEncoder::encode).toList();
            // 空命令 / 无效命令
            default -> parsed = Collections.emptyList();
        }

        log.debug("Redis RESP-Protocol message : {}", result);

        return parsed;
    }
}